package  com.stars.home.update

import android.Manifest
import android.app.Activity
import android.app.Dialog
import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.IBinder
import android.text.Html
import android.text.method.ScrollingMovementMethod
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.fragment.app.FragmentActivity
import com.google.gson.Gson
import com.liulishuo.filedownloader.BuildConfig
import com.qmuiteam.qmui.kotlin.onClick

import java.io.File
import android.provider.Settings
import com.stars.home.App
import com.stars.home.R
import com.stars.home.update.bean.UpdateBean
import com.stars.home.update.service.UpgradeService
import com.stars.home.update.util.*
import com.stars.home.update.util.Utils.formatSize

//本地下载
fun FragmentActivity.showUpgradeDialog(data: UpdateBean) {
    val fragment = UpgradeFragment.newInstance(data)
    fragment.show(supportFragmentManager, UpgradeFragment::class.java.name)
}


class UpgradeFragment : com.trello.rxlifecycle2.components.support.RxDialogFragment() {

    companion object {
        fun newInstance(upgradeData: UpdateBean): UpgradeFragment {
            return UpgradeFragment().apply {
                arguments = Bundle().apply {
                    putString("upgradeData", Gson().toJson(upgradeData))
                }
            }
        }

        const val START_APP_INSTALL_REQUESTCODE = 0x100
        const val START_APP_STORAGE_REQUESTCODE = 0x200

        private const val TAG = "UpgradeFragment"

        private val STORAGE_PERMISSION = arrayOf(
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE
        )

        private val INSTALL_PERMISSION = arrayOf(Manifest.permission.REQUEST_INSTALL_PACKAGES)

    }

    private var upgradeData: UpdateBean? = null

    lateinit var apkPath: String
    lateinit var fileDir: File

    val apkName = "teapp.apk"

    private var mDownloadId: Int = -1


    private var mUpgradeService: UpgradeService? = null


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        if (null != arguments) {
            var data = arguments?.getString("upgradeData")
            upgradeData = Gson().fromJson(data, UpdateBean::class.java)
        }
        if (BuildConfig.DEBUG) {
            apkPath =
                Environment.getExternalStorageDirectory().absolutePath + File.separator + activity!!.packageName + File.separator + "apk"
        } else {
            apkPath = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                FileUtil.getDownloadDir().absolutePath + File.separator + "apk"
            } else {
                Environment.getExternalStorageDirectory().absolutePath + File.separator + activity!!.packageName + File.separator + "apk"
            }
        }
        fileDir = File(apkPath)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        return inflater.inflate(R.layout.dialog_version_update, null)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        dialog?.let {
            val windowManager = it.window?.windowManager
            windowManager?.let { windowManager ->
                val display = windowManager.defaultDisplay
                val layoutParams = it.window?.attributes
                layoutParams?.width = (display.width * 0.9).toInt()
                it.window?.attributes = layoutParams
            }

        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        upgradeData?.let {

            view.findViewById<TextView>(R.id.tv_upgrade_title).text = it.title
            view.findViewById<TextView>(R.id.tv_version_name).text = it.versionName
            view.findViewById<TextView>(R.id.tv_upgrade_content).text =
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
                    Html.fromHtml(it.memo)
                } else {
                    Html.fromHtml(it.memo, Html.FROM_HTML_MODE_LEGACY)
                }
            //判断是否强制更新  0 否，可以模态关闭dialog
            val isCancelable = it.isCompel == 0

            view.findViewById<ImageView>(R.id.img_upgradle_close).visibility = if (isCancelable) {
                View.VISIBLE
            } else {
                View.GONE
            }

            view.findViewById<ProgressBar>(R.id.pb_download).progress = 0
            view.findViewById<ProgressBar>(R.id.pb_download).max = 100

            view.findViewById<TextView>(R.id.tv_download_percent).text = "0%"
            view.findViewById<TextView>(R.id.tv_download_total).text = ""
            dialog?.let { mDialog ->
                mDialog.setCancelable(isCancelable)
                mDialog.setCanceledOnTouchOutside(isCancelable)
            }
        }

        //设置更新内容可以滚动
        view.findViewById<TextView>(R.id.tv_upgrade_content).movementMethod =
            ScrollingMovementMethod.getInstance()

        view.findViewById<Button>(R.id.btn_update).setOnClickListener {
            val isError = it.tag as? Boolean ?: false
            if (isError) {
                mUpgradeService?.startDownload()
                return@setOnClickListener
            }
            startUpgrade()
        }
        //按钮关闭
        view.findViewById<ImageView>(R.id.img_upgradle_close).onClick {
            dismiss()
        }

    }


    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return Dialog(activity!!, R.style.showContentDialog)
    }

    /**
     * 请求sdcard 权限
     */
    private fun requestStoragePermisson() {
        activity?.requestEachCombinedPermission(*STORAGE_PERMISSION, onGranted = {
            upgradeDownload()
        }, onSettingOrDefined = {
            showStorageDialog()
        }, onDefined = {
            showStorageDialog()
        })
    }

    private fun showStorageDialog() {


        PopuUpdataUtils.show(
            this@UpgradeFragment.context!!,
            "权限申请",
            "app需要获得手机存储权限才能提供相关服务",
            "取消",
            "去开启",
            view!!,
            object : ChoiceLocalData {
                override fun onRestuse(type: String?) {
                    if (type == "1") {
                        Utils.jumpToAppSetting(activity!!, START_APP_STORAGE_REQUESTCODE)
                    }
                }

            })


        //TODO 大致就是一个普通的提示弹窗，两个按钮
//        showDialog(title="权限申请",
//            message = "app需要获得手机存储权限才能提供相关服务",
//            positiveBtn = "去开启",
//            negativeBtn = "取消",
//            onPositiveClick = {
//                Utils.jumpToAppSetting(activity!!,START_APP_STORAGE_REQUESTCODE)
//                it.dismiss()
//            },onNegativeClick = {
//                it.dismiss()
//            })
    }


    /**
     * 获取请求安装权限
     * --未知来源
     */
    private fun requestInstallPersison() {
        activity?.requestEachCombinedPermission(*INSTALL_PERMISSION, onGranted = {
            startUpgrade()
        }, onSettingOrDefined = {
            showInstallPersmissionDialog()
        }, onDefined = {
            showInstallPersmissionDialog()
        })
    }


    /**
     * 位置来源--权限弹框
     */
    private fun showInstallPersmissionDialog() {

        PopuUpdataUtils.show(
            this@UpgradeFragment.context!!,
            "权限申请",
            "请打开app未知应用权限，才能安装应用",
            "取消",
            "去开启",
            view!!,
            object : ChoiceLocalData {
                override fun onRestuse(type: String?) {
                    if (type == "1") {
                        val packageURI = Uri.parse("package:" + App.getApp()?.packageName)
                        val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI)
                        if (intent.resolveActivity(activity!!.packageManager) != null) {
                            startActivityForResult(intent, START_APP_INSTALL_REQUESTCODE)
                        }
                    }
                }

            })


        //TODO 大致就是一个普通的提示弹窗，两个按钮
//        showDialog(title= "权限申请",
//            message = "请打开app未知应用权限，才能安装应用",
//            positiveBtn = "去开启",
//            negativeBtn = "取消",
//            onPositiveClick = {
//                val packageURI = Uri.parse("package:" + App.getApp().getPackageName())
//                val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI)
//                if(intent.resolveActivity(activity!!.packageManager) != null){
//                    startActivityForResult(intent, START_APP_INSTALL_REQUESTCODE)
//                }
//                it.dismiss()
//            },onNegativeClick = {
//                it.dismiss()
//            })
    }

    /**
     * 开始执行升级
     * 1、校验本地是否有安装包，如果存在，则校验安装包的版本是否和现存版本的版本号是否一致
     * 2、如果没有安装包，则开启下载最新包
     * 3、调用API执行安装程序
     */
    private fun startUpgrade() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //android 8.0 需增加判断是否有未知来源
            if (!activity!!.packageManager.canRequestPackageInstalls()) {
                requestInstallPersison()
                return
            }
        }
        if (checkApkExits(apkName)) {
            install()
            return
        }
        //请求安装包
        requestStoragePermisson()
    }

    private fun upgradeDownload() {
        val apkFile = File(fileDir, apkName)
        upgradeData?.let {
            if (it.isSilentDownload == 0) {
                //直接下载
                UpgradeService.bindService(context, apkFile.absolutePath, it, mDownloadService)
            } else {
                //静默下载
                UpgradeService.startService(context, apkFile.absolutePath, it)
                dismiss()
            }
        }
    }

    private fun downloadByProgress(
        soFarBytes: Int = 0,
        totalBytes: Int = 0,
        progress: Int = 0,
        isError: Boolean = false
    ) {
        view?.apply {


            view?.findViewById<Button>(R.id.btn_update)?.visibility = if (isError) {
                View.VISIBLE
            } else {
                View.GONE
            }
            if (isError) {
                view?.findViewById<Button>(R.id.btn_update)?.text = "继续下载"
                view?.findViewById<Button>(R.id.btn_update)?.tag = true
            } else {
                view?.findViewById<Button>(R.id.btn_update)?.tag = null

            }

            view?.findViewById<LinearLayout>(R.id.progressbar_layout)?.visibility = if (!isError) {
                View.VISIBLE
            } else {
                View.GONE
            }
            if (soFarBytes != 0 && totalBytes != 0) {
                view?.findViewById<ProgressBar>(R.id.pb_download)?.progress = progress
                view?.findViewById<TextView>(R.id.tv_download_percent)?.text = "${progress}%"
                view?.findViewById<TextView>(R.id.tv_download_total)?.text =
                    "${soFarBytes.formatSize()}/${totalBytes.formatSize()}"

            }
        }

    }

    override fun onResume() {
        super.onResume()
        val progress = view?.findViewById<ProgressBar>(R.id.pb_download)?.progress ?: 0
        if (progress == 100) {
            view?.findViewById<Button>(R.id.btn_update)?.visibility = View.VISIBLE
            view?.findViewById<LinearLayout>(R.id.progressbar_layout)?.visibility = View.GONE

        }
    }

    private val mDownloadService = object : ServiceConnection {
        override fun onServiceDisconnected(name: ComponentName?) {

        }

        override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) {
            mUpgradeService = (iBinder as? UpgradeService.UpgradeBinder)?.getService()
            mUpgradeService?.onUpgradeError = {
                downloadByProgress(isError = true)
            }
            mUpgradeService?.onUpgradeComplete = {
                mDownloadId = -1
                install()
                view?.let { view ->
                    view?.findViewById<Button>(R.id.btn_update)?.visibility = View.GONE
                    view?.findViewById<LinearLayout>(R.id.progressbar_layout)?.visibility =
                        View.VISIBLE

                }
                activity?.unbindService(this)
            }
            mUpgradeService?.onUpgradeProgress = { totalBytes, soFarBytes, progress ->
                downloadByProgress(soFarBytes, totalBytes, progress)
            }
            mUpgradeService?.startDownload()
        }
    }


    private fun install() {
        val apkFile = File(fileDir, apkName)
        ApkInstallUtil.install(activity!!, apkFile)
        upgradeData?.let {
            if (it.isCompel != 1) {
                //非强制升级,下载成功后，自动关闭升级弹框
                dismiss()
            }
        }
    }


    private fun checkApkExits(apkName: String): Boolean {
        if (fileDir.exists()) {
            fileDir.mkdirs()
        }
        var result = false
        val archiveFilePath = fileDir.toString() + File.separator + apkName//安装包路径
        try {
            val packageName = activity!!.packageName
            val pm = activity!!.packageManager

            val apkInfo = pm.getPackageArchiveInfo(archiveFilePath, PackageManager.GET_ACTIVITIES)
            val info = pm.getPackageInfo(context!!.packageName, 0)
            //判断安装包存在并且包名一样并且版本号不一样
            if (apkInfo != null) {
                //当前系统的版本号
                val versionCode = getVersionCode(info)
                //缓存apk包的版本号
                val apkVersionCode = getVersionCode(apkInfo)
                if (packageName.equals(
                        apkInfo.packageName,
                        ignoreCase = true
                    ) && versionCode != apkVersionCode
                ) {
                    //判断开发者传入的最新版本号是否大于缓存包的版本号，大于那么相当于没有缓存
                    result = (apkVersionCode >= upgradeData!!.version.toLong())
                }
                if (!result) {
                    //如果存在缓存包，并且包的版本号和当前版本号小或等于时，删除安装包
                    File(archiveFilePath).delete()
                }
            }
        } catch (e: Exception) {
        }
        return result
    }

    private fun getVersionCode(info: PackageInfo): Long {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            info.longVersionCode
        } else {
            info.versionCode.toLong()
        }
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            START_APP_INSTALL_REQUESTCODE -> {

                view?.findViewById<Button>(R.id.btn_update)?.visibility = View.VISIBLE
                view?.findViewById<LinearLayout>(R.id.progressbar_layout)?.visibility = View.GONE

                if (resultCode == Activity.RESULT_OK) {
                    startUpgrade()
                }
            }
            START_APP_STORAGE_REQUESTCODE -> {
                if (resultCode == Activity.RESULT_OK) {
                    upgradeDownload()
                }
            }
        }
    }


}
